<template>
  <div class="translation-page">
    <div class="container">
      <div class="toolbar">
        <div class="lang-group">
          <el-radio-group v-model="fromLang" size="default">
            <el-radio-button label="ZH">中文</el-radio-button>
            <el-radio-button label="EN">English</el-radio-button>
          </el-radio-group>
          <el-button class="swap-btn" circle @click="swapLangs" :disabled="fromLang === toLang">
            🔁
          </el-button>
          <el-radio-group v-model="toLang" size="default">
            <el-radio-button label="ZH">中文</el-radio-button>
            <el-radio-button label="EN">English</el-radio-button>
          </el-radio-group>
        </div>
        <div class="actions">
          <el-button type="primary" :loading="loading" @click="handleTranslate">翻译</el-button>
          <el-button @click="clearAll">清空</el-button>
        </div>
      </div>

      <div class="panes">
        <div class="pane">
          <div class="pane-toolbar">
            <button class="icon-btn" :disabled="!inputText.trim()" @click="speakInput" title="朗读">
              <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path fill="currentColor" d="M3 10v4a1 1 0 0 0 1 1h3.382a1 1 0 0 1 .724.309L11.3 18.5c.63.66 1.7.2 1.7-.74V6.24c0-.94-1.07-1.4-1.7-.74L8.106 8.691A1 1 0 0 1 7.382 9H4a1 1 0 0 0-1 1Zm14.586-5.414l-1.172 1.172A7 7 0 0 1 19 12c0 2.004-.83 3.814-2.172 5.172l1.172 1.172A8.999 8.999 0 0 0 21 12a8.999 8.999 0 0 0-3.414-7.414ZM16 6.828 14.828 8A5 5 0 0 1 17 12a5 5 0 0 1-2.172 4l1.172 1.172A6.999 6.999 0 0 0 18.999 12 7 7 0 0 0 16 6.828Z"/></svg>
            </button>
            <button class="icon-btn" :disabled="!inputText.trim()" @click="copyInput" title="复制">
              <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path fill="currentColor" d="M16 1H4a2 2 0 0 0-2 2v12h2V3h12V1Zm3 4H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2Zm0 16H8V7h11v14Z"/></svg>
            </button>
          </div>
          <textarea
            v-model="inputText"
            class="text-area"
            placeholder="请输入要翻译的内容..."
            @keydown.ctrl.enter.prevent="handleTranslate"
          />
          <div class="hint">按 Ctrl+Enter 快速翻译</div>
        </div>
        <div class="pane">
          <div class="pane-toolbar">
            <button class="icon-btn" :disabled="!outputText" @click="speakOutput" title="朗读">
              <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path fill="currentColor" d="M3 10v4a1 1 0 0 0 1 1h3.382a1 1 0 0 1 .724.309L11.3 18.5c.63.66 1.7.2 1.7-.74V6.24c0-.94-1.07-1.4-1.7-.74L8.106 8.691A1 1 0 0 1 7.382 9H4a1 1 0 0 0-1 1Zm14.586-5.414l-1.172 1.172A7 7 0 0 1 19 12c0 2.004-.83 3.814-2.172 5.172l1.172 1.172A8.999 8.999 0 0 0 21 12a8.999 8.999 0 0 0-3.414-7.414ZM16 6.828 14.828 8A5 5 0 0 1 17 12a5 5 0 0 1-2.172 4l1.172 1.172A6.999 6.999 0 0 0 18.999 12 7 7 0 0 0 16 6.828Z"/></svg>
            </button>
            <button class="icon-btn" :disabled="!outputText" @click="copyOutput" title="复制">
              <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path fill="currentColor" d="M16 1H4a2 2 0 0 0-2 2v12h2V3h12V1Zm3 4H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2Zm0 16H8V7h11v14Z"/></svg>
            </button>
          </div>
          <textarea
            readonly
            class="text-area output"
            :value="outputText"
            placeholder="翻译结果会显示在这里"
          />
          <div class="hint right"></div>
        </div>
      </div>
    </div>
  </div>
  
</template>

<script setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { translate } from '@/apis/word.js'

const inputText = ref('')
const outputText = ref('')
const loading = ref(false)
const voices = ref([])
const speaking = ref(false)

// Only Chinese(ZH) and English(EN)
const fromLang = ref('ZH')
const toLang = ref('EN')

const swapLangs = () => {
  if (fromLang.value === toLang.value) return
  const tmp = fromLang.value
  fromLang.value = toLang.value
  toLang.value = tmp
  // 同步已有结果的语义：不清空文本
}

const handleTranslate = async () => {
  if (!inputText.value.trim()) {
    ElMessage.warning('请输入要翻译的内容')
    return
  }
  if (fromLang.value === toLang.value) {
    ElMessage.warning('源语言与目标语言不能相同')
    return
  }
  try {
    loading.value = true
    const { code, data, msg } = await translate({
      text: inputText.value,
      fromLang: fromLang.value,
      toLang: toLang.value
    })
    if (code === 200 || typeof data === 'string') {
      outputText.value = data || ''
    } else {
      ElMessage.warning(msg || '翻译失败，请稍后重试')
    }
  } catch (e) {
    ElMessage.error('网络异常，请稍后重试')
  } finally {
    loading.value = false
  }
}

const clearAll = () => {
  inputText.value = ''
  outputText.value = ''
}

const copyOutput = async () => {
  try {
    await navigator.clipboard.writeText(outputText.value)
    ElMessage.success('已复制到剪贴板')
  } catch {
    ElMessage.warning('复制失败，请手动选择文本复制')
  }
}

const copyInput = async () => {
  try {
    await navigator.clipboard.writeText(inputText.value)
    ElMessage.success('已复制到剪贴板')
  } catch {
    ElMessage.warning('复制失败，请手动选择文本复制')
  }
}

// speech synthesis helpers
const refreshVoices = () => {
  const list = window.speechSynthesis ? window.speechSynthesis.getVoices() : []
  voices.value = list
}

if (typeof window !== 'undefined' && 'speechSynthesis' in window) {
  refreshVoices()
  window.speechSynthesis.onvoiceschanged = refreshVoices
}

const pickVoice = (langCode) => {
  if (!voices.value.length) return null
  // prefer exact language, fallback by prefix
  const exact = voices.value.find(v => v.lang && v.lang.toUpperCase().startsWith(langCode))
  if (exact) return exact
  if (langCode === 'EN') {
    return voices.value.find(v => v.lang && v.lang.toLowerCase().startsWith('en')) || null
  }
  if (langCode === 'ZH') {
    return voices.value.find(v => v.lang && (v.lang.toLowerCase().startsWith('zh') || v.lang.toLowerCase().includes('cmn'))) || null
  }
  return null
}

const speak = (text, langCode) => {
  if (!text) return
  if (!('speechSynthesis' in window)) {
    ElMessage.warning('当前浏览器不支持语音朗读')
    return
  }
  try {
    window.speechSynthesis.cancel()
    const utter = new SpeechSynthesisUtterance(text)
    const voice = pickVoice(langCode)
    if (voice) utter.voice = voice
    utter.lang = voice?.lang || (langCode === 'EN' ? 'en-US' : 'zh-CN')
    utter.rate = 1
    utter.pitch = 1
    utter.onstart = () => (speaking.value = true)
    utter.onend = () => (speaking.value = false)
    utter.onerror = () => (speaking.value = false)
    window.speechSynthesis.speak(utter)
  } catch {
    ElMessage.warning('语音播放失败')
  }
}

const speakInput = () => speak(inputText.value, fromLang.value)
const speakOutput = () => speak(outputText.value, toLang.value)
</script>

<style scoped>
.translation-page {
  display: flex;
  justify-content: center;
  padding: 24px 16px;
}

.container {
  width: 100%;
  max-width: 1100px;
}

.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  background: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 12px;
}

.lang-group {
  display: flex;
  align-items: center;
  gap: 10px;
}

.swap-btn {
  font-size: 16px;
}

.actions {
  display: flex;
  gap: 8px;
}

.panes {
  margin-top: 16px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.pane {
  background: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 12px;
  padding: 12px;
  padding-bottom: 52px; /* 为右下角工具栏腾出空间，不遮挡文本 */
  position: relative;
}

.pane-toolbar {
  position: absolute;
  right: 8px;
  bottom: 8px;
  display: flex;
  gap: 8px;
  z-index: 2;
  background: rgba(255,255,255,.85);
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: 4px;
  backdrop-filter: saturate(140%) blur(4px);
  box-shadow: 0 4px 12px rgba(0,0,0,.08);
}

.icon-btn {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  color: #4b5563;
  background: #f3f4f6;
  border: 1px solid #e5e7eb;
  cursor: pointer;
  transition: all .2s ease;
}

.icon-btn:hover:enabled {
  background: #eef2ff;
  color: #6366f1;
  border-color: #c7d2fe;
}

.icon-btn:disabled {
  opacity: .5;
  cursor: not-allowed;
}

.text-area {
  width: 100%;
  min-height: 260px;
  border: none;
  outline: none;
  resize: vertical;
  font-size: 25px;
  line-height: 1.6;
  color: #1f2937;
  background: #fafafa; /* 左右两侧统一灰色底色 */
  border-radius: 8px;
  padding: 12px; /* 给文字留出内边距，不紧贴灰底 */
}



.hint {
  position: absolute;
  bottom: 8px;
  left: 12px;
  font-size: 12px;
  color: #9ca3af;
}

.hint.right {
  right: 8px;
  left: auto;
}

@media (max-width: 900px) {
  .panes {
    grid-template-columns: 1fr;
  }
}
</style>


